// 蜂窝蜜造平台生成代码，此文件只生成一次，不需要添加到 .beeignore

package com.fowo.api.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fowo.api.controller.purchase.vo.inventoryTurnoverVo;
import com.fowo.api.entity.ReceiptProduct;
import com.fowo.api.entity.StockIn;
import com.fowo.api.entity.StockInProduct;
import com.fowo.api.entity.WarehouseBin;
import com.fowo.api.inventory.model.InventoryExchangeVo;
import com.fowo.api.inventory.model.PatternEnum;
import com.fowo.api.inventory.model.SimpleInventoryItem;
import com.fowo.api.inventory.model.TargetTypeEnum;
import com.fowo.api.inventory.model.form.InventoryExchangeFormVo;
import com.fowo.api.inventory.service.InventoryBusinessService;
import com.fowo.api.mapper.StockInMapper;
import com.fowo.api.mapper.StockInProductMapper;
import com.fowo.api.mapper.WarehouseBinMapper;
import com.fowo.api.model.fbainvoice.FBAInvoiceVo;
import com.fowo.api.model.fbainvoice.detail.FBAInvoiceDetailItemVo;
import com.fowo.api.model.quality.QualityCheckInventoryVo;
import com.fowo.api.model.quality.check.storage.QualityCheckStorageVo;
import com.fowo.api.model.receipt.product.ReceiptProductVo;
import com.fowo.api.service.ReceiptProductService;
import com.fowo.api.service.StockInProductService;
import com.fowo.api.user.model.JwtUserInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 /**
 * 质检单 服务实现类
 */
@Service
public class QualityCheckStorageServiceImpl extends QualityCheckStorageBaseServiceImpl {

    @Resource
    private ReceiptProductServiceImpl receiptProductService;
    @Resource
    private StockInProductMapper stockInProductMapper;
    @Resource
    private StockInMapper stockInMapper;
    @Resource
    private WarehouseBinMapper warehouseBinMapper;
    @Resource
    private InventoryBusinessService inventoryBusinessService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object qualityInspectionAudit(JSONObject args) throws Exception {
        final JSONArray form = args.getJSONArray("form");

        for(int i = 0 ; i < form.size() ; i++){
            final JSONObject jsonObject = form.getJSONObject(i);

            QualityCheckStorageVo qualityCheckStorageVo = super.getVoById(jsonObject.getLong("id"));
            Assert.notNull(qualityCheckStorageVo,"质检单不存在，请刷新重试！");
            // 更新质检单

            qualityCheckStorageVo.setQcStatus("2");
            super.update(qualityCheckStorageVo);

            final Integer allProductGoodNum = qualityCheckStorageVo.getAllProductGoodNum();
            final Integer allProductBadNum = qualityCheckStorageVo.getAllProductBadNum();
            final Integer productReceiveNum = qualityCheckStorageVo.getProductReceiveNum().intValue();

            // 更新收货单
            ReceiptProduct receiptProduct = receiptProductService.getById(qualityCheckStorageVo.getReceiptProductId());
            Assert.notNull(receiptProduct,"收货单不存在，请联系管理员！");
            receiptProduct.setProductGoodNum((receiptProduct.getProductGoodNum() == null ? 0 : receiptProduct.getProductGoodNum()) + allProductGoodNum);
            receiptProduct.setProductBadNum((receiptProduct.getProductBadNum() == null ? 0 : receiptProduct.getProductBadNum()) + allProductBadNum);
            receiptProduct.setTestedQuantity((receiptProduct.getTestedQuantity() == null ? 0 : receiptProduct.getTestedQuantity())+Long.valueOf(allProductGoodNum + allProductBadNum));
            receiptProduct.setQcStatus("1");
            receiptProduct.setNoQcNum(receiptProduct.getNoQcNum() - receiptProduct.getReflecti());
            receiptProduct.setReflecti(receiptProduct.getReflecti() - productReceiveNum);
            receiptProduct.setQsMessage(qualityCheckStorageVo.getId());
            receiptProduct.setLastUpdateTime(new Date());
            receiptProductService.updateById(receiptProduct);

            // 更新入库单

            StockInProduct stockInProduct = stockInProductMapper.selectOne(Wrappers.lambdaQuery(StockInProduct.class).eq(StockInProduct::getReceiptProductId,qualityCheckStorageVo.getReceiptProductId()));
            Assert.notNull(stockInProduct,"入库单产品不存在，请联系管理员！");
            Long fromBinId = stockInProduct.getPositions();
            final WarehouseBin warehouseBin = warehouseBinMapper.selectById(qualityCheckStorageVo.getWhbCodeGoodId());
            Assert.notNull(warehouseBin,"仓位不存在，请重新设置！");

            Integer quantity = Convert.toInt(stockInProduct.getQuantity(), 0);
//            Integer allProductGoodNum = Convert.toInt(jsonObject.getInteger("allProductGoodNum"), 0);
            stockInProduct.setQuantity(quantity+allProductGoodNum);

            Integer defectiveProduct = Convert.toInt(stockInProduct.getDefectiveProduct(), 0);
//            Integer allProductBadNum = Convert.toInt(jsonObject.getInteger("allProductBadNum"), 0);
            stockInProduct.setDefectiveProduct(defectiveProduct+ allProductBadNum);
            stockInProduct.setWaitQuantity(stockInProduct.getWaitQuantity() - productReceiveNum);

            Integer waitPutaway = Convert.toInt(stockInProduct.getWaitPutaway(), 0);
            stockInProduct.setWaitPutaway(warehouseBin.getType().equals("5") ? waitPutaway : (waitPutaway + allProductGoodNum));

            stockInProduct.setPositions(qualityCheckStorageVo.getWhbCodeGoodId());
            stockInProduct.setDefectiveProductPosition(qualityCheckStorageVo.getWhbCodeBadId());
            stockInProductMapper.updateById(stockInProduct);


            // 良品移库
            inventoryBusinessService.exchange(prepareStockInGood(qualityCheckStorageVo));

            qualityCheckStorageVo.setWaitInspection(fromBinId);
            InventoryExchangeFormVo goodFormVo = prepareGoodExchange(qualityCheckStorageVo);
            inventoryBusinessService.exchange(goodFormVo);

            // 次品移库
            inventoryBusinessService.exchange(prepareStockInBad(qualityCheckStorageVo));
            InventoryExchangeFormVo badFormVo = prepareBadExchange(qualityCheckStorageVo);
            inventoryBusinessService.exchange(badFormVo);
        }
        return 1;
    }

    /**
     * 仓库转移
     * @param vo
     * @return
     * @throws Exception
     */
    protected InventoryExchangeFormVo prepareFinishPickingInventory(QualityCheckInventoryVo vo) throws Exception {
        JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
        InventoryExchangeFormVo formVo = new InventoryExchangeFormVo();
        formVo.setSupportNegative(true);
        formVo.setFrom(TargetTypeEnum.Inspected);
        formVo.setTo(vo.getTarget());
        formVo.setFormNum(vo.getQcSn());
        formVo.setFormOperator(jwtUserInfo.getUserId().toString());
        formVo.setDocumentType("质检移库");
        if(ObjectUtils.isEmpty(vo.getWid())){
            throw new Exception("出仓库 为空");
        }
        formVo.setFromStockId(vo.getWid());
        if(ObjectUtils.isEmpty(vo.getWid())){
            throw new Exception("入仓库 为空");
        }
        formVo.setToStockId(vo.getWid());
        formVo.setModel(PatternEnum.FIFO);

        SimpleInventoryItem inventoryItem = new SimpleInventoryItem();
        inventoryItem.setId(vo.getProductId());
        InventoryExchangeVo exchangeItem = new InventoryExchangeVo();
        exchangeItem.setItem(inventoryItem);
        exchangeItem.setQty(BigDecimal.valueOf(vo.getQuantity()));
        exchangeItem.setShopId(String.valueOf(vo.getShopId()).equals("null")? null:String.valueOf(vo.getShopId()));
        exchangeItem.setFnSku( String.valueOf(vo.getFnskuName()).equals("null")? null:String.valueOf(vo.getFnskuName()));
        exchangeItem.setCustomId(vo.getId());
        exchangeItem.setCustomBdId(null);
        formVo.add(exchangeItem);
        return formVo;
    }

    /**
     * 仓位转移
     * @param vo
     * @return
     * @throws Exception
     */
    protected InventoryExchangeFormVo prepareInventoryTurnover(QualityCheckInventoryVo vo)
            throws Exception {
        JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();

        InventoryExchangeFormVo formVo = new InventoryExchangeFormVo();
        formVo.setFrom(vo.getTarget());
        formVo.setTo(vo.getTarget());
        formVo.setFormNum(vo.getQcSn());
        formVo.setFormOperator(jwtUserInfo.getUserId().toString());
        formVo.setFromStockId(vo.getWid());
        formVo.setToStockId(vo.getWid());
        formVo.setModel(PatternEnum.FIFO);
        formVo.setDocumentType("质检移库");
        SimpleInventoryItem inventoryItem = new SimpleInventoryItem();
        inventoryItem.setId(vo.getProductId());
        InventoryExchangeVo exchangeItem = new InventoryExchangeVo();
        exchangeItem.setItem(inventoryItem);
        exchangeItem.setQty(BigDecimal.valueOf(vo.getQuantity()));
        exchangeItem.setShopId(
                String.valueOf(vo.getShopId()).equals("null")
                        ? null
                        : String.valueOf(vo.getShopId())
        );
        exchangeItem.setFnSku(
                String.valueOf(vo.getFnskuName()).equals("null")
                        ? null
                        : String.valueOf(vo.getFnskuName())
        );
        Map<Long, Integer> binIds = new HashMap<>();
        binIds.put(
                vo.getFromBinId(),
                Integer.parseInt(
                        String.valueOf(vo.getQuantity()).equals("null")
                                ? "0"
                                : String.valueOf(vo.getQuantity())
                )
        );
        exchangeItem.setFromBinIds(binIds);
        Map<Long, Integer> toBinIds = new HashMap<>();
        toBinIds.put(
                vo.getToBinId(),
                Integer.parseInt(
                        String.valueOf(vo.getQuantity()).equals("null")
                                ? "0"
                                : String.valueOf(vo.getQuantity())
                )
        );
        exchangeItem.setToBinIds(toBinIds);
        exchangeItem.setFromBinIdsType(TargetTypeEnum.Normal);
        exchangeItem.setToBinIdsType(TargetTypeEnum.Normal);
        exchangeItem.setCustomId(vo.getId());
        exchangeItem.setCustomBdId(null);
        formVo.add(exchangeItem);
        return formVo;
    }

    /**
     * 批量撤销
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void bulkRevocation(List<Long> ids) throws Exception {
        for(Long id : ids){
            qualityCheckStorageRevocationAction.run(id);
        }
    }
}

